#include "client.h"
int getsfile(int netfd,char *filename);
char* cmd_table[] = { "ls","cd","gets","puts","pwd","remove","mkdir","rmdir" };

int is_cmd_legal(char* cmd, char** cmd_table,int len) {

    int i = 0;
    while (i<len) {
        if (strcmp(cmd, cmd_table[i])==0) {
            return 0;
        }
        i++;
    }

    return -1;
}

//分割命令
int cmd_separation(char *cmd_string,char *cmd,char *arg)
{
    int len= SIZE(cmd_table);
    char* p = cmd_string;
    int i = 0;
    while ((*p) != ' ' && (*p) != '\n'&&(*p)!='\0') {//分离出命令存到cmd
        cmd[i] = *p;
        p++;
        ++i;
    }

    int ret1=is_cmd_legal(cmd,cmd_table,len);
    if(ret1==-1)
    {
        return -1;
    }

    if (*p=='\0') {//无参命令
        arg = "\0";
        return 0;
    }
    p++;

    i = 0;
    while (*p != '\0') {
        arg[i++] = *p;
        p++;
    }
    return 0;
}


//接收发出命令后，服务端返回的信息
int recv_msg(int netfd,char *buf)
{
    int length;
    recvn(netfd,&length,sizeof(int));
    recvn(netfd,buf,length);
    return 0;
}

//向客户端发送命令信息
int send_msg(int netfd,char *buf)
{
    int length;
    length = strlen(buf);
    send(netfd,&length,sizeof(int),0);
    send(netfd,buf,length,0);
    return 0;
}

int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr *)&serverAddr, sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"connect");
    char cmd_string[100]={0};
    char cmd[10]={0};
    char arg[100]={0};
    char cmd_ret_msg[100]={0};
    char name[20]={0};
    char password[100]={0};
    char isserver_connect[10]={0};
    while(1)
    {
        memset(name,0,sizeof(name));
        memset(password,0,sizeof(password));
        printf("请输入用户名:\n");
        scanf("%s",name);
        printf("请输入密码:\n");
        scanf("%s",password);
        int c;
        while((c=getchar())!='\n'&&c!=EOF);
        send_msg(sockfd,name);
        send_msg(sockfd,password);
        memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
        recv_msg(sockfd,cmd_ret_msg);
        printf("%s\n",cmd_ret_msg);
        if(strcmp(cmd_ret_msg,"验证通过!")==0)
        {
            memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
            recv_msg(sockfd,cmd_ret_msg);
            printf("%s",cmd_ret_msg);
            memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
            recv_msg(sockfd,cmd_ret_msg);
            printf("%s",cmd_ret_msg);

            break;
        }
    }
    int flag=0;
    while(1)
    {
        memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
        memset(cmd,0,sizeof(cmd));
        memset(arg,0,sizeof(arg));
        if(flag!=1){
            char exit_msg[10]={0};
            recv(sockfd,exit_msg,sizeof(exit_msg),0);
            if(exit_msg[0]=='\0'){
                flag =-1;
            }
        }
        
        
        
        
        fgets(cmd_string,100,stdin);
        cmd_string[strcspn(cmd_string,"\n")]='\0';
        if(strcmp(cmd_string,"quit")==0)
        {
            break;
        }

        int cmd_ret =cmd_separation(cmd_string,cmd,arg);
        if(flag==-1)
        {
            memset(isserver_connect,0,sizeof(isserver_connect));
            int exit_ret=recv(sockfd,isserver_connect,sizeof(isserver_connect),0);
            if(exit_ret==0)
            {
                printf("服务器已关闭！\n");
                break;
            }
        }
        if(cmd_ret==-1)
        {
            printf("%s命令错误\n",cmd);
            flag=1;
            continue;
        }
        flag=0;

        send_msg(sockfd,cmd);
        send_msg(sockfd,arg);

        if(strcmp(cmd,"gets")==0)
        {
            int retnum = 0;
            send_msg(sockfd,arg);
            recv(sockfd,&retnum,sizeof(retnum),0);
            if(retnum==-1){
                printf("文件名错误!\n");
                continue;
            }
            printf("找到文件!\n");
            getsfile(sockfd,arg);
            send(sockfd,"1",1,0);
        }else if(strcmp(cmd,"puts")==0){
            sendFile(sockfd,arg);
        }
        else
        {
            //如果不是下载命令就打印返回的信息
            recv_msg(sockfd,cmd_ret_msg);
            printf("%s",cmd_ret_msg);
        }
    }
    close(sockfd);
    return 0;
}
int getsfile(int netfd,char *filename){
    ssize_t fileLength=0;
    int fd=open(filename,O_RDWR,0666);
    if(fd==-1){
        fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);
    }
    ERROR_CHECK(fd,-1,"open");
    struct stat statbuf;
    fstat (fd,&statbuf);
    fileLength =  statbuf.st_size;

    if(fileLength!=0){
        lseek(fd,fileLength,SEEK_SET);
    }   
    send(netfd,&fileLength,sizeof(ssize_t),MSG_NOSIGNAL);
    //发送总长度
    
    int length;    
    off_t filesize=0;
    recvn(netfd,&filesize,sizeof(filesize));
    printf("文件将从%5.2lf%%开始下载\n",100.0* fileLength / (filesize+fileLength));
    //filesize是总长度
    off_t cursize = fileLength;
    off_t lastsize =fileLength;  
    char buf[1024] = {0};
    while(1){
        length =0; 
        recvn(netfd,&length,sizeof(int));
        //printf("%d\n",length);

        bzero(buf,sizeof(buf));                                                     
        recvn(netfd,buf,length);
        cursize += length;
        if(cursize - lastsize > 0){
            printf("%5.2lf%%\r",100.0 * cursize / (filesize+fileLength));
            fflush(stdout);
            lastsize = cursize;
        }
        write(fd,buf,length);
        if(length==0){
            break;
        }
    }
    fflush(stdout);
    printf("100.00%%\n");
    printf("下载完成\n");
    close(fd);
    return 0;
}

